package com.turman.plyopengl

import android.content.Context
import android.opengl.GLES20
import android.opengl.GLSurfaceView
import android.opengl.Matrix
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

class SampleRenderer1(private val context: Context) : GLSurfaceView.Renderer {
    companion object {
        private const val POSITION_COMPONENT_COUNT = 4
        private const val BYTES_PER_FLOAT = 4
        private const val A_COLOR = "a_Color"
        private const val A_POSITION = "a_Position"
        private const val POINT_SIZE = "point_Size"
        private const val U_MATRIX = "u_Matrix"
        private const val COLOR_COMPONENT_COUNT = 4
        private const val STRIDE =
            (POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT) * BYTES_PER_FLOAT
    }

    private val tableVertices: FloatArray = floatArrayOf(
        // 三角形扇形，注意第二个顶点和第六个顶点的坐标完全一样,扇形绘制以第一个点为中心点
        // x y z w r g b a
        0F, 0F, 0f, 1.5f, 1f, 1f, 1f, 1f,
        -0.5F, -0.8f, 0f, 1f, 0.7f, 0.7f, 0.7f, 1f,
        0.5f, -0.8f, 0f, 1f, 0.7f, 0.7f, 0.7f, 1f,
        0.5f, 0.8f, 0f, 2f, 0.7f, 0.7f, 0.7f, 1f,
        -0.5f, 0.8f, 0f, 2f, 0.7f, 0.7f, 0.7f, 1f,
        -0.5f, -0.8f, 0f, 1f, 0.7f, 0.7f, 0.7f, 1f,
        // 中线
        -0.5F, 0F, 0f, 1.5f, 1f, 0f, 0f, 1f,
        0.5F, 0F, 0f, 1.5f, 1f, 0f, 0f, 1f,
        // 顶点
        0F, -0.4F, 0f, 1.25f, 0f, 0f, 1f, 1f,
        0F, 0.4F, 0f, 1.75f, 1f, 0f, 0f, 1f
    )


    private val vertexData: FloatBuffer = ByteBuffer
        .allocateDirect(tableVertices.size * BYTES_PER_FLOAT)
        .order(ByteOrder.nativeOrder())
        .asFloatBuffer()
        .put(tableVertices)

    private val projectionMatrix = FloatArray(16)

    private var programId = 0
    private var aColorLocation = 0
    private var aPositionLocation = 0
    private var pointSizeLocation = 0
    private var uMatrixLocation = 0

    //模型矩阵
    private val modelMatrix = FloatArray(16)

    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        GLES20.glClearColor(0f, 0f, 0f, 1f)

        val vertexShaderCode = context.readStringFromRaw(R.raw.simple_vertex_shader1)
        val fragmentShaderCode = context.readStringFromRaw(R.raw.simple_fragment_shader1)

        val vertexShader = ShaderHelper.compileVertexShader(vertexShaderCode)
        val fragmentShader = ShaderHelper.compileFragmentShader(fragmentShaderCode)

        programId = ShaderHelper.linkProgram(vertexShader, fragmentShader)

        //调试模式下验证链接结果
        if (context.isDebugVersion()) {
            ShaderHelper.validateProgram(programId)
        }

        GLES20.glUseProgram(programId)

        aColorLocation = GLES20.glGetAttribLocation(programId, A_COLOR)
        aPositionLocation = GLES20.glGetAttribLocation(programId, A_POSITION)
        pointSizeLocation = GLES20.glGetAttribLocation(programId, POINT_SIZE)
        uMatrixLocation = GLES20.glGetUniformLocation(programId, U_MATRIX)

        //将顶点数据绑定到shader的a_position
        vertexData.position(0)
        GLES20.glVertexAttribPointer(
            aPositionLocation, //绑定到那个shader变量
            POSITION_COMPONENT_COUNT, //一个点有几个数据
            GLES20.GL_FLOAT, //类型
            false,
            STRIDE,  //间隔
            vertexData //内存数据
        )
        GLES20.glEnableVertexAttribArray(aPositionLocation) //启用该属性

        vertexData.position(4)
        GLES20.glVertexAttribPointer(
            aColorLocation, COLOR_COMPONENT_COUNT, GLES20.GL_FLOAT, false,
            STRIDE, vertexData
        )
        GLES20.glEnableVertexAttribArray(aColorLocation)


    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)
        //判断横竖屏，通过矩阵运算解决屏幕旋转时图像绘制比例失真问题
//        val isLandspace = width > height
//        val aspectRatio =
//            if (isLandspace) width.toFloat() / height.toFloat() else height.toFloat() / width.toFloat()
//        if (isLandspace) {
//            //横屏
//            Matrix.orthoM(projectionMatrix, 0, -aspectRatio, aspectRatio, -1f, 1f, -1f, 1f)
//        } else {
//            //竖屏
//            Matrix.orthoM(projectionMatrix, 0, -1f, 1f, -aspectRatio, aspectRatio, -1f, 1f)
//        }
        //在使用投影矩阵后，上面这种判断横竖屏的操作就不要了，所有的计算都可以通过投影矩阵来完成
        //这里创建一个垂直视角55°，视锥体近截面-1，远截面-10的矩阵
        MatrixHelper.prespectiveM(
            projectionMatrix,
            55f,
            width.toFloat() / height.toFloat(),
            1f,
            10f
        )

        //将模型矩阵设置为欸单位矩阵，然后沿着z轴平移量-2.5。
        Matrix.setIdentityM(modelMatrix, 0)
        //平移
        Matrix.translateM(modelMatrix, 0, 0f, 0f, -2.5f)
        //旋转,绕x轴旋转60
        Matrix.rotateM(modelMatrix,0,-60f,1f,0f,0f)

        //将模型矩阵和投影矩阵相乘获得最终的变换矩阵
        val temp = FloatArray(16)
        Matrix.multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0)
        System.arraycopy(temp, 0, projectionMatrix, 0, temp.size)
    }

    override fun onDrawFrame(gl: GL10?) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
        GLES20.glUniformMatrix4fv(uMatrixLocation, 1, false, projectionMatrix, 0)
        //绘制矩形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6) //绘制三角形，这里0是顶点数组的起始位置，6是取的点数，就是前6个点
        //绘制线
        GLES20.glDrawArrays(GLES20.GL_LINES, 6, 2)
        //绘制点
        GLES20.glVertexAttrib1f(pointSizeLocation, 10f)
        GLES20.glDrawArrays(GLES20.GL_POINTS, 8, 1)
        GLES20.glDrawArrays(GLES20.GL_POINTS, 9, 1)
    }
}